home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / bfd / opncls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-30  |  11.4 KB  |  532 lines

  1. /* opncls.c -- open and close a BFD.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* $Id: opncls.c,v 1.39 1992/01/30 15:30:44 sac Exp $ */
  22.  
  23. #include "bfd.h"
  24. #include "sysdep.h"
  25. #include "libbfd.h"
  26. #include "obstack.h"
  27. extern void bfd_cache_init();
  28. FILE *bfd_open_file();
  29.  
  30. /* fdopen is a loser -- we should use stdio exclusively.  Unfortunately
  31.    if we do that we can't use fcntl.  */
  32.  
  33.  
  34. #define obstack_chunk_alloc bfd_xmalloc
  35. #define obstack_chunk_free free
  36.  
  37. /* Return a new BFD.  All BFD's are allocated through this routine.  */
  38.  
  39. bfd *new_bfd()
  40. {
  41.   bfd *nbfd;
  42.  
  43.   nbfd = (bfd *)zalloc (sizeof (bfd));
  44.   if (!nbfd)
  45.     return 0;
  46.  
  47.   bfd_check_init();
  48.   obstack_begin((PTR)&nbfd->memory, 128);
  49.  
  50.   nbfd->arch_info = &bfd_default_arch_struct;
  51.  
  52.   nbfd->direction = no_direction;
  53.   nbfd->iostream = NULL;
  54.   nbfd->where = 0;
  55.   nbfd->sections = (asection *)NULL;
  56.   nbfd->format = bfd_unknown;
  57.   nbfd->my_archive = (bfd *)NULL;
  58.   nbfd->origin = 0;                   
  59.   nbfd->opened_once = false;
  60.   nbfd->output_has_begun = false;
  61.   nbfd->section_count = 0;
  62.   nbfd->usrdata = (PTR)NULL;
  63.   nbfd->sections = (asection *)NULL;
  64.   nbfd->cacheable = false;
  65.   nbfd->flags = NO_FLAGS;
  66.   nbfd->mtime_set = false;
  67.  
  68.   
  69.   return nbfd;
  70. }
  71.  
  72. /* Allocate a new BFD as a member of archive OBFD.  */
  73.  
  74. bfd *new_bfd_contained_in(obfd)
  75. bfd *obfd;
  76. {
  77.     bfd *nbfd = new_bfd();
  78.     nbfd->xvec = obfd->xvec;
  79.     nbfd->my_archive = obfd;
  80.     nbfd->direction = read_direction;
  81.     return nbfd;
  82. }
  83.  
  84. /*
  85. SECTION
  86.     Opening and Closing BFDs
  87.  
  88. */
  89.  
  90. /*
  91. FUNCTION
  92.     bfd_openr
  93.  
  94. SYNOPSIS
  95.         bfd *bfd_openr(CONST char *filename, CONST char*target);
  96.  
  97. DESCRIPTION
  98.     This function opens the file supplied (using <<fopen>>) with the target
  99.     supplied, it returns a pointer to the created BFD.
  100.  
  101.     If NULL is returned then an error has occured. Possible errors
  102.     are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
  103. */
  104.  
  105. bfd *
  106. DEFUN(bfd_openr, (filename, target),
  107.       CONST char *filename AND
  108.       CONST char *target)
  109. {
  110.   bfd *nbfd;
  111.   bfd_target *target_vec;
  112.  
  113.   nbfd = new_bfd();
  114.   if (nbfd == NULL) {
  115.     bfd_error = no_memory;
  116.     return NULL;
  117.   }
  118.  
  119.   target_vec = bfd_find_target (target, nbfd);
  120.   if (target_vec == NULL) {
  121.     bfd_error = invalid_target;
  122.     return NULL;
  123.   }
  124.  
  125.   nbfd->filename = filename;
  126.   nbfd->direction = read_direction; 
  127.  
  128.   if (bfd_open_file (nbfd) == NULL) {
  129.     bfd_error = system_call_error;    /* File didn't exist, or some such */
  130.     bfd_release(nbfd,0);
  131.     return NULL;
  132.   }
  133.   return nbfd;
  134. }
  135.  
  136.  
  137. /* Don't try to `optimize' this function:
  138.  
  139.    o - We lock using stack space so that interrupting the locking
  140.        won't cause a storage leak.
  141.    o - We open the file stream last, since we don't want to have to
  142.        close it if anything goes wrong.  Closing the stream means closing
  143.        the file descriptor too, even though we didn't open it.
  144.  */
  145.  
  146. #ifndef MYBUFSIZE
  147. #if 0
  148. /* For buffering of the files, to speed up fread. */
  149. #define MYBUFSIZE 65536
  150. char *fileBuffers[BFD_CACHE_MAX_OPEN];
  151. #endif
  152. #endif
  153.  
  154. /*
  155. FUNCTION
  156.          bfd_fdopenr
  157.  
  158. SYNOPSIS
  159.          bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
  160.  
  161. DESCRIPTION
  162.          bfd_fdopenr is to bfd_fopenr much like  fdopen is to fopen.
  163.      It opens a BFD on a file already described by the @var{fd}
  164.      supplied. 
  165.  
  166.          Possible errors are no_memory, invalid_target and system_call
  167.      error.
  168. */
  169.  
  170. bfd *
  171. DEFUN(bfd_fdopenr,(filename, target, fd),
  172.       CONST char *filename AND
  173.       CONST char *target AND
  174.       int fd)
  175. {
  176.   bfd *nbfd;
  177.   bfd_target *target_vec;
  178.   int fdflags;
  179.  
  180.   bfd_error = system_call_error;
  181.   
  182. #ifdef NO_FCNTL
  183.   fdflags = O_RDWR;            /* Assume full access */
  184. #else
  185.   fdflags = fcntl (fd, F_GETFL, NULL);
  186. #endif
  187.   if (fdflags == -1) return NULL;
  188.  
  189.   nbfd = new_bfd();
  190.  
  191.   if (nbfd == NULL) {
  192.     bfd_error = no_memory;
  193.     return NULL;
  194.   }
  195.  
  196.   target_vec = bfd_find_target (target, nbfd);
  197.   if (target_vec == NULL) {
  198.     bfd_error = invalid_target;
  199.     return NULL;
  200.   }
  201.  
  202. #ifdef FASCIST_FDOPEN
  203.   nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); 
  204. #else
  205.   /* if the fd were open for read only, this still would not hurt: */
  206.   nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); 
  207. #endif
  208.   if (nbfd->iostream == NULL) {
  209.     (void) obstack_free (&nbfd->memory, (PTR)0);
  210.     return NULL;
  211.   }
  212. #if 0
  213.     fileBuffers[open_files] = (char *)malloc(MYBUFSIZE);
  214.     setbuffer(abfd->iostream, fileBuffers[open_files], MYBUFSIZE);
  215. #endif
  216.   
  217.   /* OK, put everything where it belongs */
  218.  
  219.   nbfd->filename = filename;
  220.  
  221.   /* As a special case we allow a FD open for read/write to
  222.      be written through, although doing so requires that we end
  223.      the previous clause with a preposition.  */
  224.   /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
  225.   switch (fdflags & (O_ACCMODE)) {
  226.   case O_RDONLY: nbfd->direction = read_direction; break;
  227.   case O_WRONLY: nbfd->direction = write_direction; break;  
  228.   case O_RDWR: nbfd->direction = both_direction; break;
  229.   default: abort ();
  230.   }
  231.                    
  232.   bfd_cache_init (nbfd);
  233.  
  234.   return nbfd;
  235. }
  236.  
  237. /** bfd_openw -- open for writing.
  238.   Returns a pointer to a freshly-allocated BFD on success, or NULL.
  239.  
  240.   See comment by bfd_fdopenr before you try to modify this function. */
  241.  
  242. /*
  243. FUNCTION
  244.     bfd_openw
  245.  
  246. SYNOPSIS
  247.     bfd *bfd_openw(CONST char *filename, CONST char *target);
  248.  
  249. DESCRIPTION
  250.     Creates a BFD, associated with file @var{filename}, using the
  251.     file format @var{target}, and returns a pointer to it.
  252.  
  253.     Possible errors are system_call_error, no_memory,
  254.     invalid_target. 
  255. */
  256.  
  257. bfd *
  258. DEFUN(bfd_openw,(filename, target),
  259.       CONST char *filename AND
  260.       CONST char *target)
  261. {
  262.   bfd *nbfd;
  263.   bfd_target *target_vec;
  264.   
  265.   bfd_error = system_call_error;
  266.  
  267.   /* nbfd has to point to head of malloc'ed block so that bfd_close may
  268.      reclaim it correctly. */
  269.  
  270.   nbfd = new_bfd();
  271.   if (nbfd == NULL) {
  272.     bfd_error = no_memory;
  273.     return NULL;
  274.   }
  275.  
  276.   target_vec = bfd_find_target (target, nbfd);
  277.   if (target_vec == NULL) return NULL;
  278.  
  279.   nbfd->filename = filename;
  280.   nbfd->direction = write_direction;
  281.  
  282.   if (bfd_open_file (nbfd) == NULL) {
  283.     bfd_error = system_call_error;    /* File not writeable, etc */
  284.     (void) obstack_free (&nbfd->memory, (PTR)0);
  285.     return NULL;
  286.   }
  287.   return nbfd;
  288. }
  289.  
  290. /*
  291.  
  292. FUNCTION
  293.     bfd_close
  294.  
  295. SYNOPSIS
  296.     boolean bfd_close(bfd *);
  297.  
  298. DESCRIPTION
  299.  
  300.     This function closes a BFD. If the BFD was open for writing,
  301.     then pending operations are completed and the file written out
  302.     and closed. If the created file is executable, then
  303.     <<chmod>> is called to mark it as such.
  304.  
  305.     All memory attached to the BFD's obstacks is released. 
  306.  
  307. RETURNS
  308.     <<true>> is returned if all is ok, otherwise <<false>>.
  309. */
  310.  
  311.  
  312. boolean
  313. DEFUN(bfd_close,(abfd),
  314.       bfd *abfd)
  315. {
  316.   if (!bfd_read_p(abfd))
  317.     if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
  318.       return false;
  319.  
  320.   if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
  321.  
  322.   bfd_cache_close(abfd);
  323.  
  324.   /* If the file was open for writing and is now executable,
  325.      make it so */
  326.   if (abfd->direction == write_direction 
  327.       && abfd->flags & EXEC_P) {
  328.     struct stat buf;
  329.     stat(abfd->filename, &buf);
  330. #ifndef S_IXUSR
  331. #define S_IXUSR 0100    /* Execute by owner.  */
  332. #endif
  333. #ifndef S_IXGRP
  334. #define S_IXGRP 0010    /* Execute by group.  */
  335. #endif
  336. #ifndef S_IXOTH
  337. #define S_IXOTH 0001    /* Execute by others.  */
  338. #endif
  339.  
  340.     chmod(abfd->filename, 0777  & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
  341.   }
  342.   (void) obstack_free (&abfd->memory, (PTR)0);
  343.   (void) free(abfd);
  344.   return true;
  345. }
  346.  
  347. /*
  348. FUNCTION
  349.     bfd_close_all_done
  350.  
  351. SYNOPSIS
  352.     boolean bfd_close_all_done(bfd *);
  353.  
  354. DESCRIPTION
  355.     This function closes a BFD. It differs from <<bfd_close>>
  356.     since it does not complete any pending operations.  This
  357.     routine would be used if the application had just used BFD for
  358.     swapping and didn't want to use any of the writing code.
  359.  
  360.     If the created file is executable, then <<chmod>> is called
  361.     to mark it as such.
  362.  
  363.     All memory attached to the BFD's obstacks is released. 
  364.  
  365. RETURNS
  366.     <<true>> is returned if all is ok, otherwise <<false>>.
  367.  
  368. */
  369.  
  370. boolean
  371. DEFUN(bfd_close_all_done,(abfd),
  372.       bfd *abfd)
  373. {
  374.   bfd_cache_close(abfd);
  375.  
  376.   /* If the file was open for writing and is now executable,
  377.      make it so */
  378.   if (abfd->direction == write_direction 
  379.       && abfd->flags & EXEC_P) {
  380.     struct stat buf;
  381.     stat(abfd->filename, &buf);
  382. #ifndef S_IXUSR
  383. #define S_IXUSR 0100    /* Execute by owner.  */
  384. #endif
  385. #ifndef S_IXGRP
  386. #define S_IXGRP 0010    /* Execute by group.  */
  387. #endif
  388. #ifndef S_IXOTH
  389. #define S_IXOTH 0001    /* Execute by others.  */
  390. #endif
  391.  
  392.     chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
  393.   }
  394.   (void) obstack_free (&abfd->memory, (PTR)0);
  395.   (void) free(abfd);
  396.   return true;
  397. }
  398.  
  399.  
  400. /*
  401. FUNCTION    
  402.     bfd_alloc_size
  403.  
  404. SYNOPSIS
  405.     bfd_size_type bfd_alloc_size(bfd *abfd);
  406.  
  407. DESCRIPTION
  408.         Return the number of bytes in the obstacks connected to the
  409.     supplied BFD.
  410.  
  411. */
  412.  
  413. bfd_size_type
  414. DEFUN(bfd_alloc_size,(abfd),
  415.       bfd *abfd)
  416. {
  417.   struct _obstack_chunk *chunk = abfd->memory.chunk;
  418.   size_t size = 0;
  419.   while (chunk) {
  420.     size += chunk->limit - &(chunk->contents[0]);
  421.     chunk = chunk->prev;
  422.   }
  423.   return size;
  424. }
  425.  
  426.  
  427.  
  428. /*
  429. FUNCTION
  430.     bfd_create
  431.  
  432. SYNOPSIS
  433.     bfd *bfd_create(CONST char *filename, bfd *template);
  434.  
  435. DESCRIPTION
  436.     This routine creates a new BFD in the manner of
  437.     <<bfd_openw>>, but without opening a file. The new BFD
  438.     takes the target from the target used by @var{template}. The
  439.     format is always set to <<bfd_object>>. 
  440.  
  441. */
  442.  
  443. bfd *
  444. DEFUN(bfd_create,(filename, template),
  445.       CONST char *filename AND
  446.       bfd *template)
  447. {
  448.   bfd *nbfd = new_bfd();
  449.   if (nbfd == (bfd *)NULL) {
  450.     bfd_error = no_memory;
  451.     return (bfd *)NULL;
  452.   }
  453.   nbfd->filename = filename;
  454.   if(template) {
  455.     nbfd->xvec = template->xvec;
  456.   }
  457.   nbfd->direction = no_direction;
  458.   bfd_set_format(nbfd, bfd_object);
  459.   return nbfd;
  460. }
  461.  
  462. /* 
  463. INTERNAL_FUNCTION
  464.     bfd_alloc_by_size_t
  465.  
  466. SYNOPSIS
  467.     PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
  468.  
  469. DESCRIPTION
  470.     This function allocates a block of memory in the obstack
  471.     attatched to <<abfd>> and returns a pointer to it.
  472. */
  473.  
  474.  
  475. PTR 
  476. DEFUN(bfd_alloc_by_size_t,(abfd, size),
  477.       bfd *abfd AND
  478.       size_t size)
  479. {
  480.   PTR res = obstack_alloc(&(abfd->memory), size);
  481.   return res;
  482. }
  483.  
  484. DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
  485.       bfd *abfd AND
  486.       PTR ptr AND
  487.       bfd_size_type size)
  488. {
  489.   (void)   obstack_grow(&(abfd->memory), ptr, size);
  490. }
  491. DEFUN(PTR bfd_alloc_finish,(abfd),
  492.       bfd *abfd)
  493. {
  494.   return obstack_finish(&(abfd->memory));
  495. }
  496.  
  497. DEFUN(PTR bfd_alloc, (abfd, size),
  498.       bfd *abfd AND
  499.       bfd_size_type size)
  500. {
  501.   return bfd_alloc_by_size_t(abfd, (size_t)size);
  502. }
  503.  
  504. DEFUN(PTR bfd_zalloc,(abfd, size),
  505.       bfd *abfd AND
  506.       bfd_size_type size)
  507. {
  508.   PTR res = bfd_alloc(abfd, size);
  509.   memset(res, 0, (size_t)size);
  510.   return res;
  511. }
  512.  
  513. DEFUN(PTR bfd_realloc,(abfd, old, size),
  514.       bfd *abfd AND
  515.       PTR old AND
  516.       bfd_size_type size)
  517. {
  518.   PTR res = bfd_alloc(abfd, size);
  519.   memcpy(res, old, (size_t)size);
  520.   return res;
  521. }
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.